<?php
namespace app\madmin\controller;
use app\madmin\model\SystemRuleModel;
use app\madmin\model\SystemLexiconModel;
use app\madmin\model\SystemConfigModel;
use app\madmin\model\WechatKeyModel;
use app\madmin\model\WechatConfsModel;
use app\madmin\model\MallConfsModel;
use think\Controller;

/**
 * 继承控制器
 * @author  黄明杰 vx:HMJ125855
 * @version 20190101
 */
class PublicBase extends Controller{

	# 访问空的方法
    public function _empty(){
        return $this->fetch('PublicBase/show404');
    }

	# 初始信息方法
	protected function _initialize(){
		# 登录信息
    	$Admin = $this->checkLogin();
    	$this->assign('Admin', $Admin);

        # 左侧菜单
        $Menus = $this->getMenuCache($Admin['AdminID'], $Admin['AdminRule']);
        $this->assign('Menus', $Menus);

        # 当前地址
        # $Module     = strtolower(request()->module());
        $Controller = strtolower(request()->controller());
        $Action     = strtolower(request()->action());
        $Url        = $Controller."/".$Action;

        # 权限判断
        if($Admin['AdminID'] != 1){
            if(!in_array($Url, ['index/index'])){
                $Auth = new \com\Auth();
                if(!$Auth->check($Url, $Admin['AdminID'])){
                    $this->ShowData(2, lang('XtDlZwQx'));
                }
            }
        }

        # 网站配置
        $System = cache('System');
        if(empty($System)){
            $System = $this->getConfigList();
        }
        config($System);
    }

    /**
     * 获取登录信息
     * @return  Int
     */
	protected function checkLogin(){
		$AdminID = session('AdminID');
        $AdminUser = session('AdminUser');
        $AdminRule = session('AdminRule');
        $AdminToken = session('AdminToken');

        if(!empty($AdminID) && !empty($AdminUser) && !empty($AdminRule) && !empty($AdminToken)){
            # 获取成员令牌
            $Token = cache('SystemToken');

            if(!empty($Token[$AdminID]) && $Token[$AdminID] == $AdminToken){
                return ['AdminID'=>$AdminID, 'AdminUser'=>$AdminUser, 'AdminRule'=>$AdminRule, 'AdminToken'=>$AdminToken];
            }else{
                $this->ShowData(2, lang('XtDlLpSx'), url('SystemLogin/showOn'));
            }
        }else{
            $this->ShowData(2, lang('XtDlCxDl'), url('SystemLogin/showOn'));
        }
	}

	/**
     * 获取菜单缓存
     * @param   Int     $UID        唯一标识
     * @param   String  $Rules      权限内容
     * @return  Array
     */
    protected function getMenuCache($UID, $Rules){
        $Menus = cache('Menus_'.$UID);

        if(empty($Menus)){
            $Menus = $this->getMenuLists($UID, $Rules);
        }

        return $Menus;
    }

    /**
     * 获取菜单列表
     * @param   Int     $UID        唯一标识
     * @param   String  $Rules      权限内容
     * @return  Array
     */
    protected function getMenuLists($UID, $Rules){
        $SystemRule = new SystemRuleModel;

        $Lists = $SystemRule->mAll(['rule_id'=>['in', $Rules], 'rule_state'=>1, 'rule_show'=>1], '*', 'rule_sort DESC,rule_id ASC');

        # $Menus = ObjectToArray($SystemRule::mMenu($Lists));

        $Menus = $SystemRule::mMenu($Lists);

        cache('Menus_'.$UID, $Menus);

        return $Menus;
    }

    /**
     * 获取列表查询
     * @return  Array
     */
    protected function getFormWhere(){
        $Where = [];

        $input_type = input('param.input_type');
        $input_text = input('param.input_text');
        if(!empty($input_type) && !empty($input_text)){
            $Where[$input_type] = $input_text;
        }

        $this->assign('input_type', $input_type);
        $this->assign('input_text', $input_text);

        $time_type = input('param.time_type');
        $start_time = input('param.start_time');
        $end_time = input('param.end_time');
        if(!empty($time_type) && !empty($start_time) && !empty($end_time)){
            $Where[$time_type] = ['between', [strtotime($start_time.' 00:00:00'), strtotime($end_time.' 23:59:59')]];
        }

        $this->assign('time_type', $time_type);
        $this->assign('start_time', $start_time);
        $this->assign('end_time', $end_time);

        $other_type = input('param.other_type');
        $start_num = input('param.start_num');
        $end_num = input('param.end_num');
        if(!empty($other_type) && !empty($start_num) && !empty($end_num)){
            $Where[$other_type] = ['between', [strtotime($start_num), strtotime($end_num)]];
        }

        $this->assign('other_type', $other_type);
        $this->assign('start_num', $start_num);
        $this->assign('end_num', $end_num);

        $log_member = input('param.log_member');
        if(!empty($log_member)){
            $Where['log_member'] = $log_member;
        }

        $this->assign('log_member', $log_member);

        $log_type = input('param.log_type');
        if(!empty($log_type)){
            $Where['log_type'] = $log_type;
        }

        $this->assign('log_type', $log_type);

        $member_status = input('param.member_status');
        if(!empty($member_status)){
            $Where['member_status'] = $member_status;
        }

        $this->assign('member_status', $member_status);

        $config_type = input('param.config_type');
        if(!empty($config_type)){
            $Where['config_type'] = $config_type;
        }

        $this->assign('config_type', $config_type);

        $config_group = input('param.config_group');
        if(!empty($config_group)){
            $Where['config_group'] = $config_group;
        }

        $this->assign('config_group', $config_group);

        $backup_type = input('param.backup_type');
        if(!empty($backup_type)){
            $Where['backup_type'] = $backup_type;
        }
        $this->assign('backup_type', $backup_type);

        $date_type = input('param.date_type');
        $this->assign('date_type', $date_type);

        return $Where;
    }

    /**
     * 创建统计日期
     * @param   Int     $Begin      开始时间(必须为时间戳)
     * @param   Int     $End        结束时间(必须为时间戳)
     * @param   Int     $Type       时间类型 1:获取年月/2:获取年月日
     * @return  Array
    */
    protected function makeDateTime($Begin, $End, $Type){
        if($Type == 1){//获取月数
            $Type = '+1 month';
            $Data = 'Y-m';
        }else if($Type == 2){//获取日数
            $Type = '+1 day';
            $Data = 'Y-m-d';
        }

        $Array = [];
        $Array[0]['time'] = date($Data, $Begin);//开始时间
        $Array[0]['year'] = date('Y', $Begin);//年
        $Array[0]['month'] = date('m', $Begin);//月
        $Array[0]['day'] = date('d', $Begin);//日

        $Index = 1;

        while(($Begin = strtotime($Type, $Begin)) <= $End){
            $Array[$Index]['time'] = date($Data, $Begin);//取得递增日月;
            $Array[$Index]['year'] = date('Y', $Begin);//年
            $Array[$Index]['month'] = date('m', $Begin);//月
            $Array[$Index]['day'] = date('d', $Begin);//日

            $Index++;
        }

        return $Array; 
    }

    /**
     * 生成统计日期
     * @param   Int     $Type       时间类型1:获取年月/2:获取年月日
     * @return  Array
    */
    protected function makeDateType($Type){
        $Backs = [];

        switch($Type){
            case 1:
                # 查询今天
                $BegToday = mktime(0,0,0,date('m'),date('d'),date('Y'));
                $EndToday = mktime(23,59,59,date('m'),date('d'),date('Y'));

                $Backs['where'] = ['between', [$BegToday, $EndToday]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegToday, $EndToday, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 2:
                # 查询昨天
                $BegYesterday = mktime(0, 0, 0, date('m'),date('d')-1,date('Y'));
                $EndYesterday = mktime(23, 59, 59, date('m'),date('d')-1, date('Y'));

                $Backs['where'] = ['between', [$BegYesterday, $EndYesterday]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegYesterday, $EndYesterday, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 3:
                # 查询本周
                $BegThisWeek = strtotime(date('Y-m-d',strtotime("this week Monday",time())));
                $EndThisWeek = strtotime(date('Y-m-d',strtotime("this week Sunday",time()))) + 24 * 3600 - 1;

                $Backs['where'] = ['between time', [$BegThisWeek, $EndThisWeek]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegThisWeek, $EndThisWeek, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 4:
                # 查询上周
                $BegLastWeek = strtotime(date('Y-m-d',strtotime("last week Monday",time())));
                $EndLastWeek = strtotime(date('Y-m-d',strtotime("last week Sunday",time()))) + 24 * 3600 - 1;

                $Backs['where'] = ['between', [$BegLastWeek, $EndLastWeek]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegLastWeek, $EndLastWeek, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 5:
                # 查询本月
                $BegThisMonth = mktime(0,0,0,date('m'),1,date('Y'));
                $EndThisMonth = mktime(23,59,59,date('m'),date('t'),date('Y'));
                
                $Backs['where'] = ['between', [$BegThisMonth, $EndThisMonth]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegThisMonth, $EndThisMonth, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 6:
                # 查询上月
                $BegLastMonth = mktime(0,0,0,date('m')- 1,1,date('Y'));  
                $EndLastMonth = mktime(23,59,59,date('m')-1,date('t',$BegLastMonth),date('Y'));

                $Backs['where'] = ['between', [$BegLastMonth, $EndLastMonth]];
                $Backs['types'] = 2;
                $Backs['dates'] = $this->makeDateTime($BegLastMonth, $EndLastMonth, $Backs['types']);
                $Backs['group'] = 'month,day';

                break;
            case 7:
                # 查询本年
                $BegThisYear = mktime(0,0,0,1,1,date('Y'));
                $EndThisYear = mktime(23,59,59,12,31,date('Y'));

                $Backs['where'] = ['between', [$BegThisYear, $EndThisYear]];
                $Backs['types'] = 1;
                $Backs['dates'] = $this->makeDateTime($BegThisYear, $EndThisYear, $Backs['types']);
                $Backs['group'] = 'month';

                break;
            case 8:
                # 查询去年
                $BegLastYear = mktime(0,0,0,1,1,date('Y')-1);
                $EndLastYear = mktime(23,59,59,12,31,date('Y')-1);

                $Backs['where'] = ['between', [$BegLastYear, $EndLastYear]];
                $Backs['types'] = 1;
                $Backs['dates'] = $this->makeDateTime($BegLastYear, $EndLastYear, $Backs['types']);
                $Backs['group'] = 'month';

                break;
        }

        $this->assign('date_type', $Type);

        return $Backs;
    }

    /**
     * 生成日期列表
     * @param   Array   $List       查询数组
     * @param   Array   $Date       日期数组
     * @param   Int     $Type       匹配类型 1:匹配年月/2:匹配年月日
     * @param   Int     $Nums       循环次数
     * @return  Array
    */
    protected function makeDateList($List, $Date, $Type, $Nums){
        $Array = [];
        
        foreach($Date as $k => $v){
            $Data = [];

            //匹配筛选年月日
            foreach($List as $j => $p){
                if($Type == 1){
                    if($v['year'] == $p['year'] && $v['month'] == str_pad($p['month'], 2, "0", STR_PAD_LEFT)){
                        $Data = $List[$j];//匹配成功赋值
                        
                        unset($List[$j]);//清空查询数组的下标

                        break;
                    }
                }else if($Type == 2){
                    if($v['year'] == $p['year'] && $v['month'] == str_pad($p['month'], 2, "0", STR_PAD_LEFT) && $v['day'] == str_pad($p['day'], 2, "0", STR_PAD_LEFT)){
                        $Data = $List[$j];//匹配成功赋值
                        
                        unset($List[$j]);//清空查询数组的下标

                        break;
                    }
                }
            }

            if(!empty($Data)){
                $Array[$k]['date'] = '<font style="color: #000">'.$v['time'].'</font>';

                for($i = 0; $i < $Nums; $i++){
                    $Num = $Data['num'.$i] ? $Data['num'.$i] : 0;
                    $Array[$k]['num'.$i] = '<font style="color: #000">'.$Num.'</font>';
                }
            }else{
                $Array[$k]['date'] = $v['time'];

                for($i = 0; $i < $Nums; $i++){
                    $Array[$k]['num'.$i] = 0;
                }
            }
        }

        return $Array;
    }

    /**
     * 获取词典缓存
     * @param   String  $Name       词典标识
     * @return  Array
     */
    protected function getLexiconCache($Name){
        $Lexicon = cache('Lexicon');

        if(!empty($Lexicon)){
            if(!empty($Lexicon[$Name])){
                $Array = $Lexicon[$Name];
            }else{
                $Array = $this->getLexiconList($Name);
            }
        }else{
            $Array = $this->getLexiconList($Name);
        }

        return $Array;
    }

    /**
     * 获取词典列表
     * @param   String  $Name       词典标识
     * @return  Array
     */
    protected function getLexiconList($Name){
        $SystemLexicon = new SystemLexiconModel;

        $Lists = $SystemLexicon->mField(['lexicon_name'=>$Name], 'lexicon_content');

        $Lexicon = cache('Lexicon');

        if(!empty($Lists)){
            $Array = arrayMultisort(unserialize($Lists), 'content_sort');

            $Lexicon[$Name] = $Array;

            cache('Lexicon', $Lexicon);

            return $Array;
        }else{
            unset($Lexicon[$Name]);

            cache('Lexicon', $Lexicon);
        }
    }

    /**
     * 下载表格列表
     * @param   String  $Head       表格头部
     * @param   String  $List       表格内容
     * @param   String  $Name       表格名称
     * @return  Array
     */
    public function outDataExcel($Head, $List, $Name){
        vendor('PHPExcel.PHPExcel');
        $Excel = new \PHPExcel();

        # 设置Excel编号
        $Num = ord("A");
        # 遍历Excel头部
        foreach($Head as $v){
            $Excel->setActiveSheetIndex(0)->setCellValue(chr($Num) . '1', $v['name']);

            if(isset($v['center'])){
                # 设置列表居中
                $Excel->setActiveSheetIndex(0)->getStyle(chr($Num))->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
            }
            if(isset($v['width'])){
                # 设置列表宽度
                $Excel->setActiveSheetIndex(0)->getColumnDimension(chr($Num))->setWidth(10);
            }
            $Num++;
        }
        # 遍历Excel内容
        $Index = 2;
        foreach($List as $Rows){
            $Num = ord("A");
            foreach($Rows as $v){
                $Excel->getActiveSheet()->setCellValue(chr($Num) . $Index, $v);
                $Num++;
            }
            $Index++;
        }
        # 设置Excel名称
        $FileName = $Name.date('YmdHi',time()).'.xls';
        # 设置Excel表格
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header('Content-Disposition:inline;filename="'.$FileName.'"');
        # 生成Excel文件
        $objWriter = \PHPExcel_IOFactory::createWriter($Excel, 'Excel5');
        # 下载Excel文件
        $objWriter->save('php://output');exit;
    }

    /**
     * 获取配置列表
     * @return  Array
     */
	protected function getConfigList(){
        $SystemConfig = new SystemConfigModel;

        $Lists = $SystemConfig->mAll([], 'config_id,config_name,config_value');

        $Array = [];

        if(!empty($Lists)){
            foreach($Lists as $k => $v){
                $Array[$v['config_name']] = $v['config_value'];
            }

            cache('System', $Array);
        }

        return $Array;
	}

    /*************************Wechat Start*************************/

    # 获取微信消息列表信息
    protected function WechatMessageLists($Text){
        $WechatKey = new WechatKeyModel;

        $Lists = $WechatKey->mInfo(['key_name'=>$Text, 'key_state'=>1]);

        $Array = cache('WechatMessage');

        if(!empty($Lists)){
            $Array[md5($Text)] = $Lists;

            cache('WechatMessage', $Array);
        }else{
            unset($Array[md5($Text)]);

            cache('WechatMessage', $Array);
        }

        return $Array;
    }

    /**
     * 获取微信配置缓存信息
     * @return  Array
     */
    protected function WechatConfigCache(){
        $WechatConfig = cache('WechatConfig');

        if(empty($WechatConfig)){
            $Array = $this->WechatConfigLists();
        }else{
            $Array = $WechatConfig;
        }

        return $Array;
    }

    /**
     * 获取微信配置列表信息
     * @return  Array
     */
    protected function WechatConfigLists(){
        $WechatConfig = new WechatConfigModel;

        $Lists = $WechatConfig->mAll([], '*');

        $Array = [];

        if(!empty($Lists)){
            foreach($Lists as $k => $v){
                $Array[$v['config_name']] = $v['config_value'];
            }

            cache('WechatConfig', $Array);
        }

        return $Array;
    }

    /**
     * 获取微信AccessToken缓存信息
     * @return  Array
     */
    protected function WechatAccessTokenCache(){
        $Access = cache('WechatAccess');

        # 判断缓存AccessToken是否存在
        if(!empty($Access)){
            $Times = time();

            #判断缓存AccessToken是否过期
            if($Access['access_times'] > $Times){
                $Array = $Access;
            }else{
                $Array = $this->WechatAccessTokenSends();
            }
        }else{
            $Array = $this->WechatAccessTokenSends();
        }

        return $Array;
    }

    /**
     * 获取微信AccessToken请求信息
     * @return  Array
     */
    protected function WechatAccessTokenSends(){
        $Config = $this->WechatConfigCache();

        if(!empty($Config['WECHAT_APPID']) && !empty($Config['WECHAT_SECRET'])){
            # 请求AccessToken链接
            $Urls = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$Config['WECHAT_APPID'].'&secret='.$Config['WECHAT_SECRET'];

            $Back = CurlGet($Urls);

            # 判断是否请求成功
            if(!empty($Back['access_token'])){
                $Times = time();

                $Array = [];
                $Array['access_token'] = $Back['access_token'];
                $Array['access_times'] = $Times + $Back['expires_in'];

                cache('WechatAccess', $Array);

                return $Array;
            }else{
                return false;
            }
        }

        return false;
    }

    /**************************Wechat End**************************/

    /**************************Mall Start**************************/

    /**
     * 获取商城配置缓存信息
     * @return  Array
     */
    protected function MallConfigCache(){
        $MallConfig = cache('MallConfig');

        if(empty($MallConfig)){
            $Array = $this->MallConfigLists();
        }else{
            $Array = $MallConfig;
        }

        return $Array;
    }

    /**
     * 获取商城配置列表信息
     * @return  Array
     */
    protected function MallConfigLists(){
        $MallConfig = new MallConfsModel;

        $Lists = $MallConfig->mAll([], '*');

        $Array = [];

        if(!empty($Lists)){
            foreach($Lists as $k => $v){
                $Array[$v['confs_name']] = $v['confs_value'];
            }

            cache('MallConfig', $Array);
        }

        return $Array;
    }

    /***************************Mall End***************************/

}